//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package cfca.seal.front.service.ws.impl;

import cfca.sadk.algorithm.sm2.SM2PrivateKey;
import cfca.sadk.lib.crypto.JCrypto;
import cfca.sadk.lib.crypto.Session;
import cfca.sadk.util.Base64;
import cfca.sadk.util.CertUtil;
import cfca.sadk.util.Signature;
import cfca.sadk.x509.certificate.X509CRL;
import cfca.sadk.x509.certificate.X509Cert;
import cfca.seal.bean.AdminUser;
import cfca.seal.bean.OperationLog;
import cfca.seal.bean.Organization;
import cfca.seal.bean.Seal;
import cfca.seal.bean.SealCert;
import cfca.seal.dao.main.IAdminUserDao;
import cfca.seal.dao.main.IOperationLogDao;
import cfca.seal.dao.main.IOrganizationDao;
import cfca.seal.dao.main.ISealCertDao;
import cfca.seal.dao.main.ISealDao;
import cfca.seal.exception.CodeException;
import cfca.seal.front.service.FunctionType;
import cfca.seal.front.service.ws.IWebSealService;
import cfca.seal.front.service.ws.bean.VerifyBean;
import cfca.seal.front.service.ws.bean.WebSealBean;
import cfca.seal.front.service.ws.util.ValidityUtil;
import cfca.seal.maker.bean.SignInfo;
import cfca.seal.maker.bean.SignResult;
import cfca.seal.maker.bean.SignSource;
import cfca.seal.maker.bean.SoftSeal;
import cfca.seal.maker.bean.UsbKeySeal;
import cfca.seal.maker.util.SealExtracter;
import cfca.seal.maker.util.WebSeal;
import cfca.seal.maker.util.WebSealUtil;
import cfca.seal.mananger.CrlManager;
import cfca.seal.mananger.OperationLogManager;
import cfca.seal.mananger.SealManager;
import cfca.seal.mananger.TrustCertManager;
import cfca.seal.system.Env;
import cfca.seal.util.EncryptUtil;
import cfca.seal.util.JHARDUtil;
import cfca.seal.util.SealCertUtil;
import cfca.seal.util.StringUtil;
import cfca.seal.util.TimeUtil;
import cfca.seal.util.VerifyUtil;
import java.security.PrivateKey;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WebSealServiceImpl implements IWebSealService {
  private static final Logger log = LoggerFactory.getLogger("service_sys");
  @Resource
  IOperationLogDao operationLogDao;
  @Resource
  ISealDao sealDao;
  @Resource
  ISealCertDao sealCertDao;
  @Resource
  IAdminUserDao adminUserDao;
  @Resource
  IOrganizationDao orgDao;

  public WebSealServiceImpl() {
  }

  public byte[] signWebSeal(String sourceBase64, String sealStrategyXml) throws CodeException {
    OperationLog operationLog = OperationLogManager.getInstance(FunctionType.signWebSeal.toString(), "WEB签章");
    byte[] signData = "".getBytes();
    String orgId = "";
    log.info("WEB签章开始");
    log.info("签章策略：" + sealStrategyXml);

    try {
      WebSealBean webSealBean = new WebSealBean(sealStrategyXml);
      operationLog.setObjectId(webSealBean.getSealCode());
      log.info("web签章：签章人:" + webSealBean.getSealPerson() + ",签章地点:" + webSealBean.getSealLocation() + ",签章理由:" + webSealBean.getSealReason() + ",开始");
      ValidityUtil.checkParamForSignWebSeal(webSealBean);
      if (StringUtil.isEmpty(sourceBase64)) {
        throw new CodeException("C3041", "签章原文不能为空");
      }

      Seal sealBean = null;
      if ("sqlite".equals(Env.databaseType)) {
        sealBean = SealManager.getInstance().getSealByCode(webSealBean.getSealCode());
      } else {
        sealBean = this.sealDao.getSealByCode(webSealBean.getSealCode());
      }

      this.checkSealInfo(webSealBean.getSealPassword(), sealBean);
      String sourceString = new String(Base64.decode(sourceBase64));
      WebSeal webSeal = new WebSeal();
      if (0 == sealBean.getCertType()) {
        SignResult signResult = WebSealUtil.getSignResultFromSeal(sealBean.getSealData(), EncryptUtil.decrypto(sealBean.getSealPwd()), EncryptUtil.decrypto(sealBean.getSealPfxPwd()), sealBean.getSealImageData(), webSealBean.getSealLocation(), webSealBean.getSealReason());
        signData = webSeal.signWebSeal(signResult, sourceString.getBytes(), EncryptUtil.decrypto(sealBean.getSealPfxPwd()));
      } else if (1 == sealBean.getCertType() || 2 == sealBean.getCertType()) {
        SealCert sealCert = this.sealCertDao.getSealCertById(sealBean.getSealCertId());
        X509Cert cert = new X509Cert(sealCert.getPublickCertData());
        JCrypto.getInstance().initialize(sealCert.getDevice(), (Object)null);
        Session session = JCrypto.getInstance().openSession(sealCert.getDevice());
        boolean certType = true;
        PrivateKey privateKey = null;
        if (sealCert.getDevice().equals("JHARD_LIB")) {
          privateKey = JHARDUtil.getPrivateKeyFromHard(sealCert.getKeyId(), session);
        } else if (sealCert.getDevice().equals("JSOFT_LIB")) {
          sealCert.decryptCiphertext(sealCert);
          if ("SHA1RSA".equals(sealCert.getCertAlg())) {
            privateKey = (PrivateKey)SealCertUtil.getRSAPrivateKey(Base64.decode(sealCert.getPrivateKeyData()));
            certType = true;
          } else {
            privateKey = SM2PrivateKey.getInstance(Base64.decode(sealCert.getPrivateKeyData()));
            certType = false;
          }
        }

        String userName = "";
        String orgName = "";
        AdminUser adminUser = this.adminUserDao.getManagerById(webSealBean.getSealPerson());
        if (null != adminUser) {
          userName = adminUser.getName();
          Organization org = this.orgDao.getOrganizationById(adminUser.getOrganizationId());
          if (null != org) {
            orgName = org.getName();
          }
        }

        UsbKeySeal usbKeySeal = new UsbKeySeal(cert, sealBean.getSealImageData(), userName, orgName, sealBean.getName());
        SignInfo signInfo = new SignInfo(webSealBean.getSealLocation(), webSealBean.getSealReason());
        SignResult signResult = new SignResult(usbKeySeal, signInfo);
        SoftSeal softSeal = new SoftSeal(signResult.getUsbKeySeal(), signInfo.getVersion());
        SignSource signSource = new SignSource(softSeal, signInfo, sourceString.getBytes());
        byte[] sourceDatas = webSeal.generateSignedSource(signSource);
        Signature signature = new Signature();
        byte[] p7data = signature.p7SignMessageDetach("sha1WithRSAEncryption", sourceDatas, (PrivateKey)privateKey, cert, session);
        signData = webSeal.signWebSeal(signResult, sourceString.getBytes(), Base64.decode(p7data), certType);
      }

      log.info("web签章：签章人:" + webSealBean.getSealPerson() + ",签章地点:" + webSealBean.getSealLocation() + ",签章理由:" + webSealBean.getSealReason() + ",结束");
      orgId = sealBean.getOrganizationId();
      log.info("WEB签章结束");
    } catch (CodeException var34) {
      CodeException ce = var34;
      operationLog.setResult(10);
      log.error("接口在进行WEB签章发生失败! ", var34);

      try {
        signData = ("<Error><ErrorCode>" + ce.getCode() + "</ErrorCode><ErrorMessage>" + ce.getMessage() + "</ErrorMessage></Error>").getBytes("UTF-8");
      } catch (Exception var33) {
        var33.printStackTrace();
      }
    } catch (Exception var35) {
      operationLog.setResult(10);
      log.error("接口在进行WEB签章发生系统异常! ", var35);

      try {
        signData = "<Error><ErrorCode>C0001</ErrorCode><ErrorMessage>接口在进行WEB签章发生系统异常!</ErrorMessage></Error>".getBytes("UTF-8");
      } catch (Exception var32) {
        var32.printStackTrace();
      }
    } finally {
      operationLog.setOrganizationId(orgId);
      this.operationLogDao.insert(operationLog);
    }

    return signData;
  }

  @Override
  public String verifyWebSeal(String webSealSource, String sourceBase64, String verifyStrategyXML) {
    OperationLog operationLog = OperationLogManager.getInstance(FunctionType.verifyWebSeal.toString(), "WEB验章");
    String result = "";
    log.info("WEB验章开始。");
    log.info("验章策略：" + verifyStrategyXML);

    try {
      VerifyBean verifyBean = new VerifyBean(verifyStrategyXML);
      ValidityUtil.checkParamForVerify(verifyBean);
      if (StringUtil.isEmpty(webSealSource)) {
        throw new CodeException("C3013", "签章结果不能为空");
      }

      if (StringUtil.isEmpty(sourceBase64)) {
        throw new CodeException("C3041", "签章原文不能为空");
      }

      String sourceString = new String(Base64.decode(sourceBase64));
      WebSeal webSeal = new WebSeal();
      boolean verify = webSeal.verifyWebSeal(webSealSource, sourceString.getBytes("UTF-8"));
      X509Cert signCert = webSeal.getSignerCert();
      if (!verify) {
        throw new CodeException("C3028", "验证签章的WEB签名失败");
      }

      int certVerifyType = Integer.parseInt(verifyBean.getVerifyType());
      if (certVerifyType > 0) {
        if (!VerifyUtil.verifyCertDate(signCert)) {
          throw new CodeException("C3029", "验证WEB签章的证书发生已过期或者还未生效");
        }

        if (certVerifyType > 1) {
          X509Cert trustCert = TrustCertManager.instance.getTrustCertByDn(signCert.getIssuer());
          if (trustCert == null) {
            throw new CodeException("C3031", "验证WEB签章的证书对应的证书链不存在");
          }

          if (!VerifyUtil.verifyCertSign(signCert, trustCert)) {
            throw new CodeException("C3029", "验证WEB签章的证书发生已过期或者还未生效");
          }
        }

        if (certVerifyType > 2) {
          X509CRL x509crl = CrlManager.getX509CRL(StringUtil.formatIssuerKey(signCert.getIssuer()));
          if (x509crl == null) {
            throw new CodeException("C3032", "验证WEB签章的证书没有对应的CRL");
          }

          if (VerifyUtil.verifyByCRL(signCert, x509crl)) {
            throw new CodeException("C3033", "验证WEB签章的证书存在已经吊销");
          }
        }
      }

      result = "<Result><Code>200</Code><Message>successfully!</Message><CertDN>" + signCert.getSubject() + "</CertDN></Result>";
      log.info("WEB验章结束。");
    } catch (CodeException var17) {
      operationLog.setResult(10);
      log.error("接口在进行WEB验章发生失败!", var17);
      result = "<Result><Code>" + var17.getCode() + "</Code><Message>" + var17.getMessage() + "</Message></Result>";
    } catch (Exception var18) {
      operationLog.setResult(10);
      log.error("接口在进行WEB验章发生系统异常!", var18);
      result = "<Result><Code>C0001</Code><Message>接口在进行WEB验章发生系统异常!</Message></Result>";
    } finally {
      this.operationLogDao.insert(operationLog);
    }

    return result;
  }

  private void CheckIsValidateCert(Seal sealBean) throws Exception {
    X509Cert x509Cert = null;
    if (0 == sealBean.getCertType()) {
      SealExtracter sEx = new SealExtracter(sealBean.getSealData(), EncryptUtil.decrypto(sealBean.getSealPfxPwd()));
      int keyType = sEx.getKeyType();
      if (1 == keyType) {
        x509Cert = CertUtil.getCertFromPFX(sealBean.getSealPfxData(), EncryptUtil.decrypto(sealBean.getSealPfxPwd()));
      } else if (2 == keyType) {
        x509Cert = CertUtil.getCertFromSM2(sealBean.getSealPfxData());
      }
    } else if (2 == sealBean.getCertType() || 1 == sealBean.getCertType()) {
      SealCert sealCert = this.sealCertDao.getSealCertById(sealBean.getSealCertId());
      x509Cert = new X509Cert(sealCert.getPublickCertData());
    }

    if (!VerifyUtil.verifyCertDate(x509Cert, TimeUtil.getCurrentTime())) {
      throw new CodeException("C9001", "证书已过期或者还未生效");
    } else {
      X509CRL x509crl = CrlManager.getX509CRL(StringUtil.formatIssuerKey(x509Cert.getIssuer()));
      if (x509crl != null && VerifyUtil.verifyByCRL(x509Cert, x509crl)) {
        throw new CodeException("C9002", "证书已经吊销");
      }
    }
  }

  private void checkSealInfo(String sealPwd, Seal sealBean) throws Exception {
    if (sealBean == null) {
      throw new CodeException("C4004", "没有找到对应的印章");
    } else if (1 != sealBean.getStatus()) {
      throw new CodeException("C4005", "印章未启用");
    } else if (-1 == sealBean.getCertType()) {
      throw new CodeException("C4006", "无证书印章，无法签章/签名");
    } else if (!EncryptUtil.decrypto(sealBean.getSealPwd()).equals(sealPwd)) {
      sealBean = null;
      throw new CodeException("C1002", "印章密码不正确");
    } else {
      this.CheckIsValidateCert(sealBean);
    }
  }
}
